// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick
import Fk
import "../components/dashboard"

/* Layout of EquipArea:
    +---------------+
    |     Weapon    |
    |     Armor     |
    |    DefRide    |
    |    OffRide    |
    |    Treasure   |
    +---------------+
*/

Item {
  id: root
  height: 90
  width: 120
  property var items: [treasureItem, weaponItem, armorItem,
    defensiveHorseItem, offensiveHorseItem]
  property var subtypes: ["treasure", "weapon", "armor",
    "defensive_ride", "offensive_ride"]
  property int length: 0
  property string sealedSlots: ""
  property alias cards: area.cards

  Column {
    anchors.fill: parent
    anchors.topMargin: 33
    anchors.leftMargin: 1
    anchors.rightMargin: -4
    spacing: 4.2
    InvisibleCardArea {
      id: area
      anchors.centerIn: parent
      // checkExisting: true
      onLengthChanged: {
        root.length = Lua.evaluate(`(function()
          return #ClientInstance:getPlayerById(Self.id):getCardIds("e")
        end)()`);
      }
    }

    property int slotItemHeight: 16

    EquipItem {
      id: weaponItem
      subtype: "weapon"
      width: parent.width
      height: parent.slotItemHeight
      x: selectable ? 10 : 0
      opacity: 0
      sealed: root.sealedSlots.includes('WeaponSlot')
      _index: 0
      Behavior on x {
        NumberAnimation { duration: 200 }
      }
    }

    EquipItem {
      id: armorItem
      subtype: "armor"
      width: parent.width
      height: parent.slotItemHeight
      x: selectable ? 10 : 0
      opacity: 0
      sealed: root.sealedSlots.includes('ArmorSlot')
      _index: 1
      Behavior on x {
        NumberAnimation { duration: 200 }
      }
    }

    EquipItem {
      id: defensiveHorseItem
      width: parent.width
      height: parent.slotItemHeight
      x: selectable ? 10 : 0
      icon: "horse"
      opacity: 0
      sealed: root.sealedSlots.includes('DefensiveRideSlot')
      _index: 2
      Behavior on x {
        NumberAnimation { duration: 200 }
      }
    }

    EquipItem {
      id: offensiveHorseItem
      width: parent.width
      height: parent.slotItemHeight
      x: selectable ? 10 : 0
      icon: "horse"
      opacity: 0
      sealed: root.sealedSlots.includes('OffensiveRideSlot')
      _index: 3
      Behavior on x {
        NumberAnimation { duration: 200 }
      }
    }

    EquipItem {
      id: treasureItem
      subtype: "treasure"
      width: parent.width
      height: parent.slotItemHeight
      x: selectable ? 10 : 0
      opacity: 0
      sealed: root.sealedSlots.includes('TreasureSlot')
      _index: 4
      Behavior on x {
        NumberAnimation { duration: 200 }
      }
    }

  }

  function add(inputs)
  {
    area.add(inputs);

    if (inputs instanceof Array) {
      for (let i = 0; i < inputs.length; i++) {
        filterInputCard(inputs[i]);
      }
    } else {
      filterInputCard(inputs);
    }
  }

  function filterInputCard(c) {
    const vcard = Lua.call("GetVirtualEquipData", parent.playerid, c.cid);
    const card = vcard || c;
    let item = items[subtypes.indexOf(card.subtype)];
    if (item) {
      const skill = Lua.evaluate(`(function()
        local card = Self:getVirtualEquip(${c.cid}) or Fk:getCardById(${c.cid})
        local skills = table.filter(card:getEquipSkills(Self),
          function(sk) return sk:getSkeleton().attached_equip ~= nil
        end)
        local ret = #skills == 1 and skills[1].name
        return ret and Self:hasSkill(ret) and ret
      end)()`);
      if (skill) {
        item.skill = skill;
      }
      item.addCard(card);
      item.selectable = false;
      item.clicked.connect(selectItem);
      item.show();
    }
  }

  function remove(outputs)
  {
    const result = area.remove(outputs);
    for (let i = 0; i < result.length; i++) {
      const card = result[i];
      for (let j = 0; j < items.length; j++) {
        const item = items[j];
        if (item.cid !== card.cid) continue;
        item.removeCard(card.cid);
        item.selectable = false;
        item.skill = "";
        item.clicked.disconnect(selectItem);
      }
    }

    return result;
  }

  function updateCardPosition(animated)
  {
    area.updateCardPosition(animated);
  }

  function selectItem(item) {
    if (item.selectable && item.cid !== 0) {
      const cid = item.cid;
      const selected = item.selected;
      if (item.skill !== "" && item.asSkill) {
        roomScene.activateSkill(item.skill, item.selected, "click"); // 藕完了
      } else {
        Lua.call("UpdateRequestUI", "CardItem", cid, "click", { selected, autoTarget: Config.autoTarget } );
      }
    }
  }

  function addSkill(skill_name) {
    if (!skill_name.endsWith('&') || length == 0) return false;
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.cid === 0) continue;
      const skill = Lua.evaluate(`(function()
        local card = Self:getVirtualEquip(${item.cid}) or Fk:getCardById(${item.cid})
        local skills = table.filter(card:getEquipSkills(Self),
          function(sk) return sk:getSkeleton().attached_equip ~= nil
        end)
        return #skills == 1 and skills[1].name or ""
      end)()`);
      if (skill === skill_name) {
        item.skill = skill;
        return skill;
      }
    }
    return false;
  }

  function loseSkill(skill_name) {
    if (!skill_name.endsWith('&') || length == 0) return false;
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.cid === 0) continue;
      if (item.skill === skill_name) {
        item.skill = "";
        item.selectable = false;
        item.selected = false;
        return true;
      }
    }
    return false;
  }

  function disableSkills() {
    if (length == 0) return;
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.cid === 0) continue;
      if (item.skill !== "") {
        item.asSkill = false;
        item.selectable = false;
        item.selected = false;
      }
    }
  }

  function applyChange(uiUpdate) // 现状：只适配只有一张牌的情况。对item操作。OL ui（唯选中时不再往右移动）
  {
    // 处理技能按钮灭 -> 处理弹出pile -> 处理技能按钮亮
    if (length == 0) return;
    uiUpdate["SkillButton"]?.forEach(skdata => {
      if (skdata.id.endsWith('&')) {
        for (let i = 0; i < items.length; i++) {
          const item = items[i];
          if (item.cid === 0) continue;
          if (item.skill === skdata.id && !skdata.enabled) {
            item.selectable = skdata.enabled;
            item.asSkill = skdata.enabled;
            item.selected = skdata.selected;
            break;
          }
        }
      }
    });
    uiUpdate["_delete"]?.forEach(data => {
      if (data.type == "CardItem" && data.ui_data.footnote === "$Equip") {
        for (let i = 0; i < items.length; i++) {
          const item = items[i];
          if (item.containCard(data.id)) {
            item.selectable = false;
            item.selected = false;
            break;
          }
        }
      }
    });
    uiUpdate["_new"]?.forEach(dat => { // 和_delete不统一，承袭Room.qml的写法
      if (dat.type == "CardItem" && dat.ui_data.footnote === "$Equip") {
        for (let i = 0; i < items.length; i++) {
          const item = items[i];
          if (item.containCard(dat.data.id)) {
            item.selectable = dat.data.enabled;
            item.selected = dat.data.selected;
            break;
          }
        }
      }
    });
    uiUpdate["CardItem"]?.forEach(cdata => {
      for (let i = 0; i < items.length; i++) {
        const item = items[i];
        if (item.containCard(cdata.id)) {
          item.selectable = cdata.enabled;
          item.asSkill = false;
          item.selected = cdata.selected;
          break;
        }
      }
    });
    uiUpdate["SkillButton"]?.forEach(skdata => {
      if (skdata.id.endsWith('&')) {
        for (let i = 0; i < items.length; i++) {
          const item = items[i];
          if (item.cid === 0) continue;
          if (item.skill === skdata.id && skdata.enabled) {
            item.selectable = skdata.enabled;
            item.asSkill = skdata.enabled;
            item.selected = skdata.selected;
            break;
          }
        }
      }
    });
    updateCardPosition(true);
  }

  function getAllCards() {
    return cards;
  }

  function update() {
    const skills = Lua.call("GetMySkills");
    let nonEquipSkills = [];
    for (const skill of skills) {
      if (!addSkill(skill)) {
        nonEquipSkills.push(skill);
      }
    }
    updateCardPosition(true);
    return nonEquipSkills;
  }
}
